home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / unixport / rsym.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-24  |  7.9 KB  |  350 lines

  1. /*
  2. Copyright William Schelter. All rights reserved.
  3.  
  4.   Use this to build an executable rsym,
  5. which will grab only the external symbols from an object file,
  6. and put them in a simple format: (cf ext_sym.h) 
  7.  
  8. This information will be used for relocation. 
  9.  
  10. to compile use cc rsym.c -o rsym  -I../h
  11. */
  12.  
  13. #define IN_RSYM 1
  14. #include <stdio.h>
  15. #include "config.h"
  16.  
  17. #ifdef SPECIAL_RSYM
  18. #include SPECIAL_RSYM
  19. #else
  20.  
  21.  
  22. /* #include "mdefs.h" */
  23. #include "ext_sym.h"
  24.  
  25.  
  26.  
  27. #ifdef ATT
  28. /* #include <ldfcn.h> */
  29. #endif
  30.  
  31. struct filehdr my_header;
  32. int nsyms;
  33. struct syment *symbol_table;
  34. char *my_string_table;
  35. char *start_address;
  36.  
  37. #ifdef RSYM_AUX
  38. #include RSYM_AUX
  39. #endif
  40.  
  41. /* our defs */
  42.  
  43. #define TABLE_SIZE 3
  44.  
  45.  
  46. #ifdef DEBUG
  47. int debug =1;
  48. #undef dprintf
  49. #define dprintf(s,ar) if(debug) { printf(" ( s )",ar) ; fflush(stdout);}
  50. #else
  51. int debug =0;
  52. #define dprintf(s,ar) 
  53. #endif
  54.  
  55.  
  56.  
  57.  
  58. /*  this program will get the external symbols from a file writing
  59. them out to a file together with their addresses */
  60. static char *outfile;
  61.  
  62. main(argc,argv)
  63. int argc ;
  64. char *argv[];
  65. {
  66.   if (argc!=3) {perror("bad arg count");
  67.         fflush(stdout);
  68.         exit(1);}
  69. #ifdef SET_BINARY_MODE
  70.   SET_BINARY_MODE
  71. #endif    
  72.   get_myself(argv[1]);
  73.   output_externals(outfile=argv[2]);
  74.   exit(0);
  75.   }
  76.  
  77. get_myself(filename)
  78. char *filename;
  79. {
  80.     unsigned int i;
  81.     FILE *fp;
  82.     int string_size=0;
  83.     extern char *malloc();
  84.         
  85.     fp = fopen(filename, RDONLY);
  86.     
  87.     if (fp == NULL) {
  88.         fprintf(stderr, "Can't open %s\n", filename);
  89.         exit(1);
  90.     }
  91.  
  92.     HEADER_SEEK(fp);
  93.     fread((char *)&my_header,sizeof(struct filehdr),1,fp);
  94.     if(N_BADMAG(my_header)){
  95.       fprintf(stderr,"Bad magic %s",filename);
  96.       exit(1);};
  97.  
  98.     nsyms=NSYMS(my_header);
  99.     symbol_table
  100.     = (struct syment *)malloc(sizeof(struct syment) * nsyms);
  101.     /*
  102.     sizeof(struct syment) and SYMESZ are not always the same.
  103.     */
  104.  
  105.     if(fseek(fp,(int)(N_SYMOFF(my_header)),0))
  106.       {fprintf(stderr,"seek error");
  107.                            exit(1);}
  108.  
  109.     for (i = 0;  i < nsyms;  i++)
  110. #ifdef HPUX
  111.     {    
  112.         fread((char *)&symbol_table[i], SYMESZ, 1, fp);
  113.         dprintf(string_size %d,string_size);
  114.         symbol_table[i].n_un.n_strx = string_size;
  115.         string_size += symbol_table[i].n_length + 1;
  116.         fseek(fp,symbol_table[i].n_length,1);
  117.           }
  118. #else    
  119.         fread((char *)&symbol_table[i], SYMESZ, 1, fp);
  120. #endif
  121.     /*
  122.     If the string table is not empty,
  123.     its length is stored after the symbol table,
  124.     This is not described in the manual, and may change in the future.
  125.     */
  126.     /* fseek(fp,N_STROFF(my_header),0);
  127.        strings follow symbol table! */
  128. #ifndef HPUX
  129. #ifdef N_STROFF
  130.     fseek(fp,N_STROFF(my_header),0);
  131. #endif    
  132.     if (fread((char *)&string_size, 4, 1, fp) > 0)    {
  133.         my_string_table = malloc(string_size);
  134.                 if(debug)
  135.           {printf(" string_size is %d fseek %d ",string_size,fseek(fp,string_size-1,1));
  136.            printf(" fseek back %d ",fseek(fp,1-string_size,1));};
  137.         fseek(fp, -4, 1);
  138.         if(string_size!=(fread(my_string_table, 1, string_size, fp)))
  139.           {dprintf( string_size was %d ,string_size);
  140.            perror("rsym could not read bad string table") ;
  141.            exit(1);}
  142.  
  143.     }
  144.     else {fprintf(stderr,"Error: There is no string table \n");
  145.              exit(1);}
  146. #else    
  147. {
  148.         char *p; 
  149.         int slen;
  150.         p = my_string_table=malloc((unsigned int)string_size);
  151.         dprintf( string table leng = %d, string_size);
  152.         fseek(fp,(int)( LESYM_OFFSET(my_header)),  0);
  153.         for (i = 0;  i < nsyms; i++)
  154.         {
  155.             fseek(fp,SYMESZ, 1);
  156.             slen = symbol_table[i].n_length;
  157.             dprintf( slen = %d,slen);
  158.             fread(p,slen,1,fp);
  159.             *((p)+slen) = '\0';
  160.             dprintf( p = %s,p );
  161.             dprintf(symbol_table[i].n_type %d,
  162.                 symbol_table[i].n_type);
  163.             p += symbol_table[i].n_length + 1;
  164.         }
  165.     }
  166. #endif
  167.     fclose(fp);
  168. }
  169.  
  170. struct lsymbol_table tab;
  171.  
  172.  
  173. output_externals(out)
  174. char *out;
  175. {FILE *symout;
  176.  char *name;
  177.  char tem[SYMNMLEN+1];
  178.  struct syment *p, *end;
  179.  tem[SYMNMLEN]=0;
  180.  tab.n_symbols=0;
  181.  tab.tot_leng=0;
  182.  symout=fopen(out,"wr");
  183.  if (!symout)
  184.    {perror(out); exit(1);};
  185.  fseek(symout,sizeof(struct lsymbol_table),0);
  186.  end = symbol_table + nsyms;
  187.  for (p = symbol_table; p < end; p++)    {
  188.    /*
  189.      Is the following check enough?
  190.      */
  191.    if (EXT_and_TEXT_BSS_DAT(p))
  192.      { name= SYM_NAME(p);
  193.        { dprintf(tab.n_symbols %d , tab.n_symbols);
  194.      tab.n_symbols++;
  195.      {int i = (p->n_value);
  196. #ifdef AIX3
  197.       if (p->n_scnum == TEXT_NSCN)
  198.         i = i + 0x10000e00;
  199.       else
  200.         i += DBEGIN;
  201.         
  202.       /* leave space for the toc entry. */
  203.  
  204. #endif      
  205.       fwrite((char *)&i,sizeof(int),1,symout);}
  206. #ifdef AIX3     
  207.       {short j=0;   fwrite((char *)&j,sizeof(short),1,symout);}
  208. #endif       
  209.      dprintf( p->n_value %d , p->n_value);
  210.      dprintf( name %s , name);
  211.      while(tab.tot_leng++,*name)
  212.        putc(*name++,symout); 
  213.      putc(0,symout);
  214.      /*      fprintf(symout,name);
  215.          fprintf(symout," %d  ", p->n_value); 
  216.          */
  217.        };
  218.        dprintf(  NUM_AUX(p) %d ,  NUM_AUX(p));
  219.        dprintf( index , (int) (p - symbol_table)  / sizeof(struct syment));
  220.        p = p + NUM_AUX(p); }
  221.  }
  222.  fseek(symout,0,0);
  223.  fwrite(&tab,sizeof(tab),1,symout);
  224.  fclose(symout);
  225. #ifdef AIX3
  226.  add_tc_offsets(outfile);
  227. #endif 
  228.  
  229.  return 0;
  230. }
  231.  
  232. #ifdef AIX3
  233. int node_compare();
  234.  
  235. struct node *
  236. find_sym(sym,name)
  237.   struct syment *sym;
  238.    char *name;
  239. { char tem[SYMNMLEN +1];
  240.   tem [SYMNMLEN] = 0;
  241.   if (name==0) name = SYM_NAME(sym);
  242.   {struct node joe;
  243.    joe.string=name;
  244.    return (struct node *)
  245.      bsearch((char *)(&joe),(char*) (c_table.ptable),
  246.              c_table.length,
  247.              sizeof(struct node), node_compare);
  248.  }}
  249.  
  250.  
  251.  
  252. add_tc_offsets(out)
  253. char *out;
  254. {FILE *symin;
  255.   char *symbols;
  256.  char *name;
  257.  int i,jj;
  258.  symin=fopen(out ,"r");
  259.  if(!symin)
  260.    perror("can't open");
  261.  
  262.  if(!fread((char *)&tab,sizeof(tab),1,symin))
  263.    perror("No header");
  264.  symbols=malloc(tab.tot_leng);
  265.  c_table.alloc_length=( (PTABLE_EXTRA+ tab.n_symbols));
  266.  (c_table.ptable) = (TABL *) malloc(sizeof(struct node) * c_table.alloc_length);
  267.  if (!(c_table.ptable)) {perror("could not allocate"); exit(1);};
  268.  i=0; c_table.length=tab.n_symbols;
  269.  while(i < tab.n_symbols)
  270.    {unsigned short tc_off;
  271.      fread((char *)&jj,sizeof(int),1,symin);
  272.      fread((char *)&tc_off,sizeof(short),1,symin);
  273.      SYM_TC_OFF(c_table,i) = tc_off;
  274.      (SYM_ADDRESS(c_table,i))=jj;
  275.      SYM_STRING(c_table,i)=symbols;
  276.       while( *(symbols++) =   getc(symin)) 
  277.        {;}
  278.      dprintf( "(name %s ",  SYM_STRING(c_table,i));
  279.      dprintf( "addr %x )"  , jj);
  280.  
  281.      i++;
  282.    }
  283.  qsort((char*)(c_table.ptable),(int)(c_table.length),
  284.        sizeof(struct node),node_compare);
  285.  {struct syment *sym, *end = symbol_table + nsyms;
  286.   char tem[SYMNMLEN+1];
  287.   int toc_anchor =0;
  288.   tem[SYMNMLEN]=0;
  289.   for (sym=symbol_table ; sym < end ; sym = sym +1+ NUM_AUX(sym))
  290.     {if( sym->n_scnum != DATA_NSCN
  291.       || NUM_AUX(sym)  == 0) continue;
  292.       if (toc_anchor == 0
  293.       && ((union auxent *)(sym+1))->x_csect.x_smclas == XMC_TC0)
  294.     {toc_anchor = sym->n_value;
  295.      continue;}
  296.       if (((union auxent *)(sym+1))->x_csect.x_smclas == XMC_TC)
  297.       { struct node joe;
  298.       struct node *answ;
  299.       name = SYM_NAME(sym);
  300.       joe.string = name;
  301.       answ = (struct node *)
  302.         bsearch((char *)(&joe),(char*) (c_table.ptable),
  303.            c_table.length,
  304.            sizeof(struct node), node_compare);
  305.       if (answ == 0) continue;
  306.       if(toc_anchor ==0) {printf("TC symbol before tco"); continue;}
  307.       answ->tc_offset = (sym->n_value - toc_anchor);
  308.     }}
  309.  
  310.   /* fix ptrgl to point to the one in the data section for shorter
  311.      branches */
  312.   
  313.   {struct node *a=find_sym(0,"myptrgl");
  314.    if (a == 0 ) printf("couldn't find ptrgl");
  315.    else 
  316.      {a->string[0]= '.';
  317.       a->string[1]= '_';
  318.       a->tc_offset = 0;}
  319.  }
  320.   
  321.  
  322.   fclose(symin);
  323.   symin=fopen(out,"w");
  324.   if(symin==0) perror("can't open");
  325.   fwrite(&tab,sizeof(tab),1,symin);
  326.   fseek(symin,sizeof(tab),0);
  327.   {int i,j;
  328.    unsigned short k;
  329.    for (i=0 ; i < tab.n_symbols ; i++)
  330.      {k = SYM_TC_OFF(c_table,i);
  331.       j= SYM_ADDRESS(c_table,i);
  332.      fwrite((char *)&j,sizeof(int),1,symin);
  333.      fwrite((char *)&k,sizeof(short),1,symin);
  334.      name = SYM_STRING(c_table,i);
  335.       while(*name)
  336.     {putc(*name,symin); *name++;} 
  337.       putc(0,symin);
  338.     }}}
  339.  fclose(symin);
  340. }
  341.  
  342.  
  343. node_compare(node1,node2)
  344. struct node *node1, *node2;
  345. { return(strcmp(node1->string, node2->string));}
  346.  
  347. #endif /*aix3 */
  348.  
  349. #endif /* SPECIAL_RSYM */
  350.